package com.terrace.core.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.core.io.ClassPathResource;

import com.terrace.core.constant.ConfigConstant;
import com.terrace.core.exception.CustomCacheException;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

/**
 * EH缓存工具类
 * @author jiangyg
 *
 */
public class EHCacheUtils {
	
	/**
	 * 缓存集合
	 */
	private static final Map<String, Cache> CACHE_MAP = new ConcurrentHashMap<String, Cache>();
	
	/**
	 * 获取缓存
	 * @param cacheName
	 * @return
	 * @throws IOException 
	 */
	public static Cache obtainCache(String cacheName) throws IOException {
		if (StringUtils.isBlank(cacheName)) {
			return null;
		}
		String enabled = ConfigConstant.value("ehcahce.enabled");
		if (!BooleanUtils.toBoolean(enabled)) {
			return null;
		}
		Cache cache = CACHE_MAP.get(cacheName);
		if (cache == null) {
			synchronized (EHCacheUtils.class) {
				if (cache == null) {
					String configFile = ConfigConstant.value("system.ehcache.config.file");
					if (StringUtils.isBlank(configFile)) {
						throw new CustomCacheException("请在[config.properties]配置文件中配置系统eh缓存配置文件[system.ehcache.config.file]路径。");
					}
					ClassPathResource resource = new ClassPathResource(configFile);
					InputStream ehcacheInputStream = resource.getInputStream();
					cache = CacheManager.create(ehcacheInputStream).getCache(cacheName);
					CACHE_MAP.put(cacheName, cache);
				}
			}
		}
		return cache;
	}
	
	/**
	 * 获取缓存的值
	 * @param cacheName
	 * @param cacheKey
	 * @return
	 * @throws IOException 
	 */
	public static Object get(String cacheName, String cacheKey) throws IOException {
		Cache cache = obtainCache(cacheName);
		if (cache == null) {
			return null;
		}
		Element el = cache.get(cacheKey);
		if (el == null) {
			return null;
		}
		return el.getObjectValue();
	}
	
	/**
	 * 存放缓存
	 * @param cacheType
	 * @param cacheKey
	 * @param cacheValue
	 * @throws IOException 
	 */
	public static void put(String cacheName, String cacheKey, Object cacheValue) throws IOException {
		Cache cache = obtainCache(cacheName);
		if (cache == null) {
			throw new CustomCacheException("缓存[" + cacheName + "]获取失败。");
		}
		Element el = new Element(cacheKey, (Serializable) cacheValue);
		cache.put(el);
	}
	
	/**
	 * 模糊移除，只要key前缀一直，就移除缓存
	 * @param cacheType
	 * @param cacheKey
	 * @throws IOException 
	 */
	public static void fuzzyRemove(String cacheName, String cacheKey) throws IOException {
		Cache cache = obtainCache(cacheName);
		List<?> keys = cache.getKeys();
		Iterator<?> iterator = keys.iterator();
		while (iterator.hasNext()) {
			String key = ObjectUtils.toString(iterator.next());
			if (StringUtils.isNotBlank(cacheKey) && StringUtils.startsWith(key, cacheKey)) {
				cache.remove(key);
			}
		}
	}
	
	/**
	 * 清空缓存
	 * @param cacheType
	 * @throws IOException
	 */
	public static void empty(String cacheName) throws IOException {
		Cache cache = obtainCache(cacheName);
		cache.removeAll();
	}

}
